<?php
class TasksController extends AppController {
	
	var $name = 'Tasks';
	
	function beforeFilter(){
		$this->belepesCheck();
		$this->setGeneralData();
		}


	function index() {
		$this->pageTitle = W2D;
		$this->Task->recursive = 0;
		
		//default form feltöltéshez adatok
		$this->set('categories', $this->Task->Category->generateList(null, 'Category.category', null, '{n}.Category.id', '{n}.Category.category'));
		$this->set('priorities', $this->Task->Priority->generateList(null, 'Priority.priority DESC', null, '{n}.Priority.id', '{n}.Priority.description'));
		$this->set('types', $this->Task->Type->generateList('Type.id != '.$this->settings['task_type_deleted'], 'Type.type', null, '{n}.Type.id', '{n}.Type.type'));
		$this->set('szuloTree', $this->getNestedTree());		
		
		//tasksfa
		$this->set('tasksfa', $this->tasksfa());
		
		//whatsnext lista
		$this->set('whatsnext',$this->whatsnext());
		
		//miből mennyi van?
		//összes
		$t = $this->Task->findCount('bid = jid-1 AND Task.id != 1');
		$this->set('totaltasks',number_format($t,0,',','.'));
		
		//összes le nem zárt
		$t = $this->Task->findCount('types_id != ' . $this->settings['task_type_finished']
					. ' AND bid = jid-1
					AND Task.id != 1');
		$this->set('opentasks',number_format($t,0,',','.'));
		
		//lejárt
		$t = $this->Task->findCount('types_id != ' . $this->settings['task_type_finished']
					. " AND due < '" . date('Y-m-d') . "'
					AND types_id = ".$this->settings['task_type_open']."
					AND bid = jid-1
					AND Task.id != 1");
		$this->set('overduedtasks',number_format($ovdt=$t,0,',','.'));
		
		//aktuális
		$t = $this->Task->findCount("types_id != " . $this->settings['task_type_finished']
					. " AND due = '" . date('Y-m-d') . "'
					AND types_id = ".$this->settings['task_type_open']."
					AND bid = jid-1
					AND Task.id != 1");
		$this->set('actualtasks',number_format($t+$ovdt,0,',','.'));		
		
		//késési pont
		$t = $this->Task->find("Task.priorities_id = Priority.id
					AND types_id = " . $this->settings['task_type_open']
					. " AND due < '" . date('Y-m-d') . "'
					AND Task.bid = Task.jid -1
					AND Task.id != 1", "SUM((DATEDIFF('".date('Y-m-d')."', Task.due) * Priority.priority)) AS osszes");
		$this->set('odp',number_format($t[0]['osszes'],0,',','.'));
		
		//lehet
		$t = $this->Task->findCount("types_id = " . $this->settings['task_type_maybe']
					. ' AND bid = jid-1
					AND Task.id != 1');
		$this->set('maybetasks',number_format($t,0,',','.'));
		
		//várakozó
		$t = $this->Task->findCount("types_id = " . $this->settings['task_type_waiting']
					. ' AND bid = jid-1
					AND Task.id != 1');
		$this->set('waitingtasks',number_format($t,0,',','.'));
		
		//verzió ellenőrzés
		$w2dver = $this->getVersions();
		if($w2dver['actual'] && $w2dver['recent'] && $w2dver['actual'] != $w2dver['recent'])
			$this->set('w2dfrissites', true);
		else
			$this->set('w2dfrissites', false);
	
		//biztonsági ellenőrzések
		$this->set('security',$this->secuCheck());
		}
		
	function integrityCheck(){
		//integritás ellenőrzés, csak a fejlesztési fázisban szükséges
		$s = 0;
		$integrityFault = array();
		
		//minden elemre igaznak kell lennie, hogy a bid+jid páratlan szám
		$bidJidParos = $this->Task->find('MOD((bid + jid), 2 ) != 1', 'Task.id');
		if($bidJidParos){
			$integrityFault[$s]['message'] = INTEGRITY_ODD;
			$integrityFault[$s]['details'] = $bidJidParos['Task']['id'];
			$s++;
			}
		
		//teljesülni kell, hogy max(jid)/2 = count(id)
		$maxJidFele = $this->Task->find(null, 'MAX(jid)/2 as maxjidfele');
		$taskDarab = $this->Task->findCount();
		if($maxJidFele[0]['maxjidfele'] != $taskDarab){
			$integrityFault[$s]['message'] = INTEGRITY_NUM;
			$integrityFault[$s]['details'] = $maxJidFele[0]['maxjidfele'] - $taskDarab;
			$s++;
			}
		
		//a bid-nek egyedinek kell lennie, ennélfogva a distinct egyenlő lesz az id-k darabszámával
		$bidSzam = $this->Task->findCount(null, 'DISTINCT bid');
		if($bidSzam != $taskDarab){
			$integrityFault[$s]['message'] = INTEGRITY_BID;
			$integrityFault[$s]['details'] = $taskDarab - $bidSzam;
			$s++;
			}
		
		//a jidnek egyedinek kell lennie ennélfogva a distinct egyenlő lesz az id-k darabszámával
		$jidSzam = $this->Task->findCount(null, 'DISTINCT jid');
		if($jidSzam != $taskDarab){
			$integrityFault[$s]['message'] = INTEGRITY_BID;
			$integrityFault[$s]['details'] = $taskDarab - $jidSzam;
			$s++;
			}
		
		if($s){
			$integrityFault['errorz'] = $s;
			return($integrityFault);
			}
		else return false;
		}
		
	/**
	* task fa lekérdezése
	*
	* @return tasksfa tömb
	* @access public
	*/
	function tasksfa(){
		$tasksfa = $this->Task->query('SELECT *
		FROM
			(SELECT node.task, (COUNT(parent.id)-1) AS depth, node.id, node.types_id, node.bid, node.jid, node.due
				FROM ' . $this->Task->tablePrefix .  $this->Task->table . ' AS node, ' . $this->Task->tablePrefix .  $this->Task->table . ' AS parent
				WHERE node.types_id != ' . $this->settings['task_type_deleted'] . '
				AND node.bid BETWEEN parent.bid AND parent.jid
				GROUP BY node.id
				ORDER BY node.bid
			) AS node

			LEFT JOIN
			
			(SELECT parent.id, (COUNT(node.id)-1) AS leszarmazottak
				FROM ' . $this->Task->tablePrefix .  $this->Task->table . ' AS node, ' . $this->Task->tablePrefix .  $this->Task->table . ' AS parent
				WHERE node.id NOT IN
					(SELECT ' . $this->Task->tablePrefix .  $this->Task->table . '.id
						FROM ' . $this->Task->tablePrefix .  $this->Task->table . '
						WHERE ' . $this->Task->tablePrefix .  $this->Task->table . '.types_id IN ('.$this->settings['task_type_deleted'].', '.$this->settings['task_type_finished'].')
					)
				AND node.bid BETWEEN parent.bid AND parent.jid
				GROUP BY parent.id
			) AS elem
			
			ON elem.id = node.id
			WHERE node.id != 1');
		return($tasksfa);
	}

	
	
	/**
	* következő feladatok lekérése
	*
	* @param $nap annak a hétnek az első napja ebben a hónapban amire kíváncsiak vagyunk
	* @return $whatsnext tömb
	* @access public
	*/
	function whatsnext($nap = null){
		//gyűjtsük ki a feladatokat melyeknek lejárati ideje kisebb mint ennek a hétnek a vége
		//ha a $nap tartalmaz - jelet, akkor havi nézetről van szó
		if(strpos($nap, '-')){
			$aHetUtolsoNapja = $nap;
			$kezdoNapLimit = '';
			$h = mktime();
			}
		else{
			//date('w') = 0:vasárnap, 6:szombat
			$napSorszam = (date('w')) ? date('w') : 7;
			if($nap && ($nap != date('d')-($napSorszam-1))){	//ha a $nap e hét hétfője, akkor figyelmen kívül kell hagyni
				if($nap<0){	//előző hónappal kell kezdeni
					$nap = -$nap;
					$aHetUtolsoNapja = date('Y-m-d',mktime(0, 0, 0, (date('m')-1), $nap+6, date('Y')));
					$kezdoNapLimit = '';
					$h = mktime(0, 0, 0, (date('m')-1), $nap, date('Y'));	//hétfő
					$eHet = true;
					}
				else{
					$aHetUtolsoNapja = date('Y-m-d',mktime(0, 0, 0, date('m'), $nap+7, date('Y')));
					$kezdoNapLimit = "AND due >= '". date('Y-m-d',mktime(0, 0, 0, date('m'), $nap, date('Y'))) . "' ";
					$h = mktime(0, 0, 0, date('m'), $nap, date('Y'));	//hétfő
					$eHet = false;
					}
				}
			else{		//aktuális heti nézet
				$napokVasarnapig = (date('w') == 0) ? 0 : (8-date('w'));
				$aHetUtolsoNapja = date('Y-m-d',mktime(0, 0, 0, date('m'), (date('j')+$napokVasarnapig), date('Y')));
				$kezdoNapLimit = '';
				$napokHetfoig = (date('w') == 0) ? 6 : (date('w')-1);
				$h = mktime(0, 0, 0, date('m'), (date('j')-$napokHetfoig), date('Y'));	//hétfő
				$eHet = true;
				}
			
			$hetfo = date('Y-m-d',$h);
			}
			
		$maybe = ($this->settings['show_maybe']) ? '' : ' AND types_id != ' . $this->settings['task_type_maybe'];
		$waiting = ($this->settings['show_waiting']) ? '' : ' AND types_id != ' . $this->settings['task_type_waiting'];
			
		$taskTabla = $this->Task->tablePrefix .  $this->Task->table;
		$priorityTabla = $this->Task->Priority->tablePrefix .  $this->Task->Priority->table;
		$categoryTabla = $this->Task->Category->tablePrefix .  $this->Task->Category->table;
		
		//ha a $nap definiált akkor csak azt a hetet kell mutatni
		$lejaratVasarnapig = $this->Task->query($p='SELECT '.$taskTabla.'.id, '.$taskTabla.'.task,
			'.$taskTabla.'.due, '.$categoryTabla.'.id, '.$taskTabla.'.types_id,
			'.$priorityTabla.'.id, '.$priorityTabla.".priority,
			IF(
				DATEDIFF('".date('Y-m-d')."', $taskTabla.due)>0,
				(
					DATEDIFF('".date('Y-m-d')."', $taskTabla.due)*".$priorityTabla.'.priority
				),
				0
			) AS kesedelmiertek
				
				FROM '.$taskTabla.', '.$categoryTabla.', '.$priorityTabla.'
				WHERE '.$taskTabla.'.categories_id = '.$categoryTabla.'.id
				AND '.$taskTabla.'.priorities_id = '.$priorityTabla.".id
				AND due <= '" . $aHetUtolsoNapja . "' " .
				$kezdoNapLimit . 
				'AND ('.$taskTabla.'.id IN
					(SELECT t1.id
						FROM (
							SELECT parent.id, count( parent.id ) AS toroltlezartleszarmazott
								FROM `'.$taskTabla.'` AS parent, '.$taskTabla.' AS node
								WHERE node.bid BETWEEN parent.bid AND parent.jid
								AND parent.jid != parent.bid +1
								AND parent.id != node.id
								AND node.types_id	IN ('.$this->settings['task_type_deleted'].", ".$this->settings['task_type_finished'].')
								GROUP BY parent.id
								ORDER BY `parent`.`id` ASC) AS t1
							
							LEFT JOIN (
							
							SELECT parent.id, count( parent.id ) AS leszarmazott
								FROM `'.$taskTabla.'` AS parent, '.$taskTabla.' AS node
								WHERE node.bid BETWEEN parent.bid AND parent.jid
								AND parent.jid != parent.bid +1
								AND parent.id != node.id
								GROUP BY parent.id
								ORDER BY `parent`.`id` ASC
								) AS t2
								
							ON t1.id = t2.id
						WHERE toroltlezartleszarmazott = leszarmazott)
				OR (jid-1 = bid))' .
				$maybe.'
				'.$waiting.'
				AND '.$taskTabla.'.id != 1
				ORDER BY due, kesedelmiertek DESC');//print $p;
		
		//t1: taskonként megadja a törölt és befejezett leszármazottak számát, levelekre nem ad vissza semmit
		//t2: taskonként megadja az összes leszármazottak számát, levelekre nem ad vissza semmit
		//visszakapjuk azokat akik levelek vagy akiknek csak és kizárólag lezárt vagy törölt gyerekei vannak
		

		$whatsnext = array();
		foreach($lejaratVasarnapig as $feladat){
			$due = explode('-', $feladat['tasks']['due']);
			$kulonbseg = ($h-(mktime(0, 0, 0, $due[1], $due[2], $due[0])))/(60*60*24);
			//ha a kulonbség>0 és a feladat törölt akkor nem kell megjelníteni
			if(!($kulonbseg>0 && $feladat['tasks']['types_id'] == $this->settings['task_type_deleted'])){
				$kulonbseg = ($kulonbseg>=0) ? 0 : round(abs($kulonbseg));
				$feladat['tasks']['kulonbseg'] = $kulonbseg;
				$feladat['tasks']['path'] = $this->getPath($feladat['tasks']['id']);
				$whatsnext[] = $feladat;
				}
			}
		
		$this->set('whatsnext', $whatsnext);
		if(isset($hetfo)) $this->set('hetfo',$hetfo);
		if(isset($eHet)) $this->set('eHet',$eHet);
		if($nap && !strpos($nap, '-')) $this->render(null, 'ajax');
		return($whatsnext);
		}
		
	function getHaviTasks(){
		//adott havi feladatok listája
		//a hónap utolsó napja
		$honapUtolsoNapja = date('Y-m-d',strtotime('-1 second',strtotime('+1 month',strtotime(date('m').'/01/'.date('Y').' 00:00:00'))));
		$this->set('whatsnext', $this->whatsnext($honapUtolsoNapja));
		$this->layout = 'havi';
		}
	
	/**
	* egy task elérési útjának lekérdezése
	*
	* @param $id a keresett task id-je
	* @return $eleresiUt stringként
	* @access public
	*/	
	function getPath($id){
		//elérési út lekéérdezése
		$path = $this->Task->query('SELECT parent.task
				FROM '.$this->Task->tablePrefix .  $this->Task->table.' AS node, '.$this->Task->tablePrefix .  $this->Task->table.' AS parent
				WHERE node.bid BETWEEN parent.bid AND parent.jid
				AND node.id = ' . $id . '
				ORDER BY parent.bid');

		array_shift($path);	//kivesszük a root elemet
		array_pop($path);		//kivesszük magát a taskot
		
		$eleresiUt = '';
		foreach($path as $p){
			$eleresiUt .=  ' / ' . $p['parent']['task'];
			}
		return($eleresiUt);
		}

	/**
	* egy task lekérdezése ajaxhoz
	*
	* @param $kimenet milyen kimeneti render kell?
	* 	whatsnext: json azokkal az adatokkal amik oda kellenek
	* 	tasklist: xhtml
	* 	raw: json minden AB-beli adattal
	* @param $id a keresett task id-je
	* @return $task tömb a task részleteivel
	* @access public
	*/
	function getTask($id){
		$task = $this->Task->read(null, $id);
		$task['Task']['path'] = $this->getPath($id);
		//$this->set('kimenet',$kimenet);
		$this->set('aTask',$task);
		$this->render(null, 'ajax');
		}

	function add($szuloid = 1){
		//taskok hozzáadása
		$szulo = $this->Task->find('Task.id='.$szuloid, 'types_id');
		if($szulo['Task']['types_id'] == $this->settings['task_type_finished'] || $szulo['Task']['types_id'] == $this->settings['task_type_deleted']){
			$this->set('message', TASK_ADD_PARENT_ERROR);
			$this->set('integrityFault',$this->integrityCheck());
			$this->set('sikeres', false);
			$this->render('add','ajax');
			}
		elseif(empty($this->data)){		//még nem küldött el adatot
			$this->set('szuloid',$szuloid);
			$this->set('szuloValues', $this->Task->find('Task.id='.$szuloid,null,null,1));
			$this->set('message', '');
			$this->set('integrityFault',$this->integrityCheck());
			$this->set('sikeres', true);
			$this->render('add','ajax');
			}
		else{		//már küldött el adatokat
			$this->data['Task']['start'] = $this->datumFormaz(null);
			$this->data['Task']['due'] = $this->datumFormaz($this->data['Task']['due']);

			$takaritoNeni = new Sanitize();
			$takaritoNeni->cleanArray($this->data);
			$this->cleanUpFields();	//date mezők pucolása
			if($bid = $this->getNewBidAfterInsert($this->data['Task']['szulo'])){	//a tranzakció eddig sikeres
				$this->data['Task']['jid'] = $bid+1;
				$this->data['Task']['bid'] = $bid;
				if($this->Task->save($this->data)){	//a tranzakció utolsó lépése is sikeres
					$integrityFault = $this->integrityCheck();
					if(!$integrityFault['errorz']){
						$this->Task->query('COMMIT');
						$this->set('message', TASK_SAVED);
						$this->set('sikeres', true);
						}
					else{
						$this->Task->query('ROLLBACK');
						$this->set('integrityFault',$integrityFault);
						$this->set('message', TASK_ADD_STRANGE_ERROR);
						$this->set('sikeres', false);
						}
					$this->data = $this->Task->read(null, $this->Task->id);
					$this->set('datas', $this->Task->find('Task.id='.$this->Task->id,null,null,1));
					$this->set('szuloTree', $this->getNestedTree());
					$this->set('szuloid', $szuloid);
					$this->set('path', $this->getPath($this->Task->id));
					$this->set('integrityFault',$this->integrityCheck());
					$this->render('add','ajax');
					exit();
					}
				else{	//a tranzakció utolsó lépése nem sikeres
					$this->Task->query('ROLLBACK');
					$this->set('message', CORRECTERRORS);
					//$this->set('categories', $this->Task->Category->generateList(null, 'Category.category', null, '{n}.Category.id', '{n}.Category.category'));
					//$this->set('priorities', $this->Task->Priority->generateList(null, 'Priority.priority DESC', null, '{n}.Priority.id', '{n}.Priority.description'));
					//$this->set('types', $this->Task->Type->generateList(null, 'Type.type', null, '{n}.Type.id', '{n}.Type.type'));
					$this->set('integrityFault',$this->integrityCheck());
					$this->set('sikeres', true);
					$this->render('add','ajax');
					}
				}
			else{		//tranzakciós hiba
				$this->set('message',TASK_ADD_TRANSACTION_ERROR);
				$this->set('integrityFault',$this->integrityCheck());
				$this->render('add','ajax');
				}
			}
		}
	
	function getNewBidAfterInsert($szuloid=null){
		//új elem hozzáadása
		//a spéci sql felépítés miatt lesz rá szükségünk
		if($szuloid){
			$result = $this->Task->find('Task.id='.$szuloid, 'jid');
			$this->Task->query('START TRANSACTION');
			//mind a jid mind a bid értéket 2-vel kell növelni
			$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . ' SET jid=jid+2 WHERE jid>' . ($result['Task']['jid']-1));  
			$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . ' SET bid=bid+2 WHERE bid>' . ($result['Task']['jid']-1));
			if($this->transactionSuccess($tranzakcio))
				return($result['Task']['jid']);
			else{
				$this->Task->query('ROLLBACK');
				return false;
				}
			}  
		else{  
			//a gyökérhez adunk valamit hozzá
			//a mostani max bid-re van szükségünk
			$result = $this->Task->find(null, 'MAX(jid) AS maxjid');
			return($result[0]['maxjid']+1);
			}  
		}

	
	/**
	* selectechez behúzott tasklista kreálása
	*
	* @param mixed $id annak a tasknak az id-je amit szerkesztünk, csak editből hívva van értéke
	* @return mixed behúzott task lista
	* @access public
	*/
	function getNestedTree($id=null){
		$ss[0] = $filter = '';
		if($id){
			$bidjid = $this->Task->find('Task.id='.$id,'bid,jid',null,1);
			$filter = ' AND (node.bid > ' . $bidjid['Task']['jid'] . ' OR node.bid < ' . $bidjid['Task']['bid'] . ')';
			}
		$szulo = $this->Task->query($p="SELECT node.id, CONCAT(REPEAT('-', COUNT(parent.task) - 1), node.task) AS task
					FROM " . $this->Task->tablePrefix .  $this->Task->table . " AS node, tasks AS parent
					WHERE node.bid BETWEEN parent.bid AND parent.jid
					AND node.types_id != " . $this->settings['task_type_finished'] .
					" AND node.types_id != " . $this->settings['task_type_deleted'] .
					$filter . "
					GROUP BY node.id
					ORDER BY node.bid");
		$z = 0;
		foreach($szulo as $s){
			$ss[$z]['id'] = $s['node']['id'];
			$ss[$z]['task'] = $s[0]['task'];
			$z++;
			}
		return($ss);
		}

	function getParentId($id){
		//az elem szülő id-jének visszanyerése
		//kérjük le a hozzá vezető utat
		$parentId = $this->Task->query('SELECT parent.id
			FROM ' . $this->Task->tablePrefix .  $this->Task->table . ' AS node, tasks AS parent
			WHERE node.bid BETWEEN parent.bid AND parent.jid
			AND node.id = '.$id.'
			ORDER BY parent.bid');
		//az utolsó előtti elem a közvetlen szülő id-je
		$s = ((count($parentId)-2)>0) ? (count($parentId)-2) : 0;
		$parentId = ($parentId[$s]['parent']['id'] == $id) ? 1 : $parentId[$s]['parent']['id'];
		return($parentId);
		}

	/**
	* SQL tranzakció sikerességének ellenőrzése
	*
	* @param array $results a tranzakcióban szereplő sql parancsok eredményeit tartalmazó tömb, a tagok siker esetén üres tömb, hiba esetén pedig nem tömb
	* @return bool siker esetén igazat ad vissza
	* @access public
	*/
	function transactionSuccess($results){
		$success = true;
		foreach($results as $r){
			if(!is_array($r)){
				$success = false;
				}
			}
		return($success);
		}


	/**
	* task dátumok átalakítása
	*
	* @param string $datum a dátum
	* @return string átjavított sql kész dátum
	* @access public
	*/
	function datumFormaz($datum = null){
		//feltételezzük, hogy a dátum év-hó-nap formában érkezik
		//todo: többnyelvűségnél ez nem így lesz
		
		if(is_array($datum))
			$datum = $datum['Task']['start'];

		//ha a dátum mező + jellel kezdődik akkor át kell alakítani ma +x nappá
		if(substr($datum,0,1) == '+')
			$datum = date('Y-m-d',mktime(0, 0, 0, date("m"), date("d")+$datum, date("Y")));

		//mindent ami nem szám --re cserélünk
		$datum = preg_replace('/\D/', '-', $datum);
		
		if(!$datum || $datum == '0000-00-00')
			$datum = date('Y-m-d');
			
		//a következő formátumokban szereténk elfogadni a dátumot:
		/*
		 12: enek a hónapnak a 12-ik napja
		 12-12: december 12
		 5-5-12: 2005 május 12
		*/
		$elvalasztok = substr_count($datum, '-');
		switch($elvalasztok){
			case 0:
				$datum = date('Y-m-d',mktime(0, 0, 0, date("m"), $datum, date("Y")));
				break;
			case 1:
				$datum = explode('-', $datum);
				$datum = date('Y-m-d',mktime(0, 0, 0, $datum[0], $datum[1], date("Y")));
				break;
			case 2:
				$datum = explode('-', $datum);
				$datum = date('Y-m-d',mktime(0, 0, 0, $datum[1], $datum[2], $datum[0]));
				break;			
			}
		
		//- visszaalakítás .-re
		$datum = str_replace('-', '.', $datum);
		return($datum);
		}

	/**
	* task szerkesztése
	*
	* @param mixed $id A szerkesztendő task id-je
	* @return nothing
	* @access public
	*/
	function edit($id = null){
		if(empty($this->data)){	//még nem küldtünk el adatot, épp lekérdezzük az aktuálisat
			$this->set('integrityFault',$this->integrityCheck());
			if(!isset($id)){
				$this->set('message',INVALIDID);
				$this->render('edit','ajax');
				}
			$this->data = $this->Task->read(null, $id);
			$this->set('szuloid', $this->getParentId($id));
			$this->data['Task']['path'] = $this->getPath($id);
			$this->set('closeable', $this->isCloseAble($id));
			$this->render('edit','ajax');
			}
		else{	//már elküldtük a formot
			$start = $this->Task->read('start', $id);
			$this->data['Task']['start'] = $this->datumFormaz($start);
			
			//ha most zártuk le a feladatot, akkor a due-ját állítsuk át mára
			if($this->data['Task']['types_id'] == $this->settings['task_type_finished'] && $this->Task->read('types_id', $id) != $this->settings['task_type_finished'])
				$this->data['Task']['due'] = $this->datumFormaz();
			else
				$this->data['Task']['due'] = $this->datumFormaz($this->data['Task']['due']);
			
			$takaritoNeni = new Sanitize();
			$takaritoNeni->cleanArray($this->data);
			//pr($this->data);die();
			$this->cleanUpFields();
			//die(pr($this->data));
			if(!isset($this->data['Task']['szulo'])){
				//$this->set('szulo', $this->getNestedTree($id));
				$this->set('szuloid', $this->data['Task']['szulo'] = $this->getParentId($id));
				}
			if($this->data['Task']['szulo'] != $this->getParentId($id)){	//ha változik a szülő, akkor áthelyezésről van szó
				//bid jid lekérés
				$gyoker = $this->Task->find('Task.id='.$id,'bid,jid',null,1);
				$ujSzulo = $this->Task->find('Task.id='.$this->data['Task']['szulo'],'bid,jid',null,1);
				//ha az új id-hez tartozó bid a régi bid jid között  van akkor maga alá csinálunk ami roppantul nem egészséges
				if($ujSzulo['Task']['bid'] > $gyoker['Task']['bid'] && $ujSzulo['Task']['bid'] < $gyoker['Task']['jid']){
					$this->set('szuloid', false);
					$this->set('hiba', true);
					$message = DEBUG ? CANNOTMOVEUNDERITSELF.':'.$ujSzulo['Task']['bid'].':::'.$gyoker['Task']['bid'] : CANNOTMOVEUNDERITSELF;
					$this->set('message', $message);
					}
				else{	//nem maga alá mozgatjuk, azaz az áthelyezés engedélyezett
					//$diff a különbség
					$diff = $gyoker['Task']['jid']-$gyoker['Task']['bid']+1;
					
					//tranzakció kezdődik
					$this->Task->query('START TRANSACTION');
					
					//a mozgatandó fa elemeinek (mozgatott task és leszármazottjai )jobb és bal id-jét negatívvá tesszük
					$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . '
													SET ' . $this->Task->tablePrefix .  $this->Task->table . '.bid = (-1)*' . $this->Task->tablePrefix .  $this->Task->table . '.bid,
														' . $this->Task->tablePrefix .  $this->Task->table . '.jid = (-1)*' . $this->Task->tablePrefix .  $this->Task->table . '.jid
													WHERE ' . $this->Task->tablePrefix .  $this->Task->table . '.bid >= ' . $gyoker['Task']['bid'] . 
														' AND ' . $this->Task->tablePrefix .  $this->Task->table . '.jid <= ' . $gyoker['Task']['jid']);
					
					//az eredeti és az új szülő közötti elemek bid jid-je is változik
					if($ujSzulo['Task']['jid'] > $gyoker['Task']['bid']){				//jobbra mozgatunk
						$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . '
														SET ' . $this->Task->tablePrefix .  $this->Task->table . '.bid = (' . $this->Task->tablePrefix .  $this->Task->table . '.bid-'.$diff.')
														WHERE ' . $this->Task->tablePrefix .  $this->Task->table . '.bid >= '.$gyoker['Task']['bid'].' 
														AND ' . $this->Task->tablePrefix .  $this->Task->table . '.bid < '.$ujSzulo['Task']['jid']);
						$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . '
														SET ' . $this->Task->tablePrefix .  $this->Task->table . '.jid = (' . $this->Task->tablePrefix .  $this->Task->table . '.jid-'.$diff.')
														WHERE ' . $this->Task->tablePrefix .  $this->Task->table . '.jid >= ' . $gyoker['Task']['bid'].' 
														AND ' . $this->Task->tablePrefix .  $this->Task->table . '.jid < '.$ujSzulo['Task']['jid']);
						}
					else{																					//balra mozgatunk
						$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . '
														SET ' . $this->Task->tablePrefix .  $this->Task->table . '.bid = (' . $this->Task->tablePrefix .  $this->Task->table . '.bid+'.$diff.')
														WHERE ' . $this->Task->tablePrefix .  $this->Task->table . '.bid >= '.$ujSzulo['Task']['jid'].' 
														AND ' . $this->Task->tablePrefix .  $this->Task->table . '.bid < '.$gyoker['Task']['bid']);
						$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . '
														SET ' . $this->Task->tablePrefix .  $this->Task->table . '.jid = (' . $this->Task->tablePrefix .  $this->Task->table . '.jid+'.$diff.')
														WHERE ' . $this->Task->tablePrefix .  $this->Task->table . '.jid >= ' . $ujSzulo['Task']['jid'].' 
														AND ' . $this->Task->tablePrefix .  $this->Task->table . '.jid < '.$gyoker['Task']['bid']);
						}
						
					//mivel magának az ujSzulonek is változhat a jid értéke újra lekérjük
					$ujSzulo = $this->Task->find('Task.id='.$this->data['Task']['szulo'],'jid',null,1);
					
					//a negatív tartományból áttesszük a fát a helyére
					$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . '
								SET ' . $this->Task->tablePrefix .  $this->Task->table . '.bid = ('.($ujSzulo['Task']['jid']-1).'-('.$gyoker['Task']['jid'].'+' . $this->Task->tablePrefix .  $this->Task->table . '.bid))
								WHERE ' . $this->Task->tablePrefix .  $this->Task->table . '.bid <= (-1)*'.$gyoker['Task']['bid'].' 
								AND ' . $this->Task->tablePrefix .  $this->Task->table . '.bid >= (-1)*'.$gyoker['Task']['jid']);
					$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . '
								SET ' . $this->Task->tablePrefix .  $this->Task->table . '.jid = ('.($ujSzulo['Task']['jid']-1).'-('.$gyoker['Task']['jid'].'+' . $this->Task->tablePrefix .  $this->Task->table . '.jid))
								WHERE ' . $this->Task->tablePrefix .  $this->Task->table . '.jid <= (-1)*'.$gyoker['Task']['bid'].' 
								AND ' . $this->Task->tablePrefix .  $this->Task->table . '.jid >= (-1)*'.$gyoker['Task']['jid']);
					
					//a $tranzakcio tömb minden elemének egy üres tömbnek kell lenni, ahol nem az ott hiba volt
					//todo: ezt ki kell cserélni trancactionSuccess hívásra
					$hiba = false;
					foreach($tranzakcio as $t){
						if(!is_array($t)){
							$hiba = true;
							$this->set('message',TASK_MOVE_ERROR);
							//tranzakció vége: rollback
							$this->Task->query('ROLLBACK');
							break;
							}
						}
					if(!$hiba){
						$this->set('message',TASK_MOVED);
						//tranzakció vége: commit
						$this->Task->query('COMMIT');
						if($this->Task->save($this->data)){
							//die(pr($this->data));
							//$this->set('categories', $this->Task->Category->generateList(null, 'Category.category', null, '{n}.Category.id', '{n}.Category.category'));
							//$this->set('szulo', $this->getNestedTree($id));
							//!!! úgy néz ki, hogy a commit némi időt vesz igénybe, és itt hol a jó id-t adja vissza a getparentid vagy még a régit
							$this->set('szuloid', $this->data['Task']['szulo']);
							//$this->set('rrd', $this->getParentId($id) . ':::'. $id . ':::' . $this->data['Task']['szulo']);
							//$this->set('priorities', $this->Task->Priority->generateList(null, 'Priority.priority DESC', null, '{n}.Priority.id', '{n}.Priority.description'));
							//$this->set('types', $this->Task->Type->generateList(null, 'Type.type', null, '{n}.Type.id', '{n}.Type.type'));
							}
						}
					}
				$this->data = $this->Task->read(null, $id);
				$this->set('integrityFault',$this->integrityCheck());
				$this->data['Task']['path'] = $this->getPath($id);
				$this->set('closeable', $this->isCloseAble($id));
				$this->set('szuloTree', $this->getNestedTree($id));
				$this->render('edit','ajax');
				}
			elseif($this->Task->save($this->data)){	//nem áthelyezés és menthető
				$this->data = $this->Task->read(null, $id);		//ennek azért kell ittlennie, hogy a dátum amegfelelő formában legyen megjelenítésnél
				$this->set('message',TASK_SAVED);
				//$this->set('categories', $this->Task->Category->generateList(null, 'Category.category', null, '{n}.Category.id', '{n}.Category.category'));
				//$this->set('szulo', $this->getNestedTree($id));
				$this->set('szuloid', $this->getParentId($id));
				//$this->set('priorities', $this->Task->Priority->generateList(null, 'Priority.priority DESC', null, '{n}.Priority.id', '{n}.Priority.description'));
				//$this->set('types', $this->Task->Type->generateList(null, 'Type.type', null, '{n}.Type.id', '{n}.Type.type'));
				$this->set('integrityFault',$this->integrityCheck());
				$this->data['Task']['path'] = $this->getPath($id);
				$this->set('closeable', $this->isCloseAble($id));
				$this->render('edit','ajax');
				}
			else{	//nem menthető, valami hiba van
				$this->set('message',CORRECTERRORS);
				//$this->set('categories', $this->Task->Category->generateList(null, 'Category.category', null, '{n}.Category.id', '{n}.Category.category'));
				//$this->set('szulo', $this->getNestedTree($id));
				$this->set('szuloid', $this->getParentId($id));
				//$this->set('priorities', $this->Task->Priority->generateList(null, 'Priority.priority DESC', null, '{n}.Priority.id', '{n}.Priority.description'));
				//$this->set('types', $this->Task->Type->generateList(null, 'Type.type', null, '{n}.Type.id', '{n}.Type.type'));
				$this->set('integrityFault',$this->integrityCheck());
				$this->data['Task']['path'] = $this->getPath($id);
				$this->set('closeable', $this->isCloseAble($id));
				$this->render('edit','ajax');
				}
			}
		}

	function isDeleteAble($id){
		/*A feladat törölhető egyszerűen vagy nem
		ha az elem egy levél akkor egybül törölhető
		vagy
		ha csak töröltnek jelölt gyerekei vannak
		*/
		if($this->isLikeLeaf($id))
			return true;
		else
			return false;
		}
	
	function delete($id = null, $arusure = false) {
		$deletedBranchId = $sikeres = false;
		if (!$id){
			$this->set('message',TASK_DELETE_NOID);
			}
		//ha az elem egy levél akkor egybül törölhető
		elseif($this->isDeleteAble($id)){
			$taskName = $this->deleteProcedure($id);
			$this->set('message',$taskName . TASK_DELETE_OK);
			$sikeres = true;
			}
		//ha teljes ágat töröl, akkor töröljük
		elseif($arusure){
			$path = $this->getPath($id);
			$taskName = $this->deleteProcedure($id);
			$this->set('message',TASK_DELETE_BRANCH_OK.$path.'/'.$taskName);
			$deletedBranchId = $id;
			$sikeres = true;
			}
		//ha nem levél akkor nem törölhető
		else{
			$this->set('message', TASK_DELETE_HAS_CHILDREN);
			$deletedBranchId = $id;
			$sikeres = false;
			}
		$this->set('deletedBranchId', $deletedBranchId);
		$this->set('sikeres',$sikeres);
		$this->set('integrityFault',$this->integrityCheck());
		$this->render('delete','ajax');
		}
	
	function deleteProcedure($id=null){
		//feladatok tölrése AB-ból
		if($id){
			$this->Task->query('START TRANSACTION');
			$eredmeny = $this->Task->find("Task.id=".$id,null,null, 1);
			$eleresiUt = $this->getPath($id);
			//a törölt taskot betesszük a deletedtasks táblába
			//valahogyan többször fut le ez a kelleténél e nélkül
			if($eredmeny['Task']['categories_id'])
				$tranzakcio[] = $this->Task->query("INSERT INTO ".$this->Task->tablePrefix.".`deletedtasks`
					(`categories_id`, `priorities_id`, `types_id`, `task`, `details`, `start`, `due`, `deleted`)
					VALUES (
						'".$eredmeny['Task']['categories_id']."',
						'".$eredmeny['Task']['priorities_id']."',
						'".$eredmeny['Task']['types_id']."',
						'".$eredmeny['Task']['task']."',
						'".$eleresiUt . " \n" . $eredmeny['Task']['details']."',
						'".$eredmeny['Task']['start']."',
						'".$eredmeny['Task']['due']."',
						'".date('Y-m-d')."')");
			//die(pr($w));
			$valtozas = $eredmeny['Task']['jid'] - $eredmeny['Task']['bid'] + 1;
			$tranzakcio[] = $this->Task->query('DELETE FROM ' . $this->Task->tablePrefix .  $this->Task->table . ' WHERE bid BETWEEN ' . $eredmeny['Task']['bid'] . ' AND ' . $eredmeny['Task']['jid']);
			$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . ' SET jid = jid-' . $valtozas . ' WHERE jid > ' . $eredmeny['Task']['jid']);
			$tranzakcio[] = $this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . ' SET bid = bid-' . $valtozas . ' WHERE bid > ' . $eredmeny['Task']['bid']);
			
			if($this->transactionSuccess($tranzakcio)){
				$this->Task->query('COMMIT');
				return $eredmeny['Task']['task'];
				}
			else{
				$this->Task->query('ROLLBACK');
				return false;
				}
			//jelöljük meg töröltként, ne töröljük ténylegesen
			/*$this->Task->query('UPDATE ' . $this->Task->tablePrefix .  $this->Task->table . ' SET types_id = ' . $this->settings['task_type_deleted']
									 . ' WHERE id = ' . $id);*/
			
			}
		else return false;
		}
		
/*	function killall(){
		//töröltként megjelöltek tényleges törlése
		$toroltek = $this->Task->findAll('' . $this->Task->tablePrefix .  $this->Task->table . '.types_id = 5', '' . $this->Task->tablePrefix .  $this->Task->table . '.id');
		foreach($toroltek as $torolt){
			$this->deleteProcedure($torolt['Task']['id']);
			}
		}	*/

	function isLikeLeaf($id){
		//az elem egy levél vagy kizárólag törölt gyerekei vannak
		if($this->isLeaf($id)) return true;
		else{
			//vannak gyerekei vizsgáljuk meg, hohgy mind törölt-e
			$eredmeny = $this->Task->find("Task.id=".$id,'bid, jid',null, 1);
			$erd = $this->Task->findCount("Task.bid > ".$eredmeny['Task']['bid']."
				AND Task.bid < ".$eredmeny['Task']['jid']."
				AND Task.types_id != " . $this->settings['task_type_deleted'], 'Task.id');
			//ha van nem törölt gyereke
			if($erd) return false;
			else return true;
			}
		}
		
	function isLeaf($id){
		//az elem levél-e?
		$eredmeny = $this->Task->find("Task.id=".$id,'bid, jid',null, 1);
		if($eredmeny['Task']['bid'] == $eredmeny['Task']['jid']-1) return true;
		else return false;
		}
		
	function allChildIsClosed($id){
		//minden leszármazott le van zárva?
		$eredmeny = $this->Task->find("Task.id=".$id,'bid, jid',null, 1);
		$gyerekSzam = $this->Task->findCount(array('bid' => 'BETWEEN ' . ($eredmeny['Task']['bid']+1) . ' AND ' . $eredmeny['Task']['jid']));
		$leZartGyerekSzam = $this->Task->findCount(array('bid' => 'BETWEEN ' . ($eredmeny['Task']['bid']+1) . ' AND ' . $eredmeny['Task']['jid'], 'types_id = '. $this->settings['task_type_finished']));
		if($gyerekSzam == $leZartGyerekSzam) return true;
		else return false;
		}
		
	
	/**
	* task lezárása
	*
	* @param $id A lezárandó task id-je
	* @param $areusure megerősítés kérése
	* @return nothing
	* @access public
	*/
	function setClosed($id, $areusure = false){
		//a feladatot lezártra állítjuk
		if($id){
			//ha az elem le van zárva akkor nyissuk vissza
			$tipus = $this->Task->find('Task.id='.$id, 'types_id');
			if($tipus['Task']['types_id'] == $this->settings['task_type_finished']){
				$this->setOpen($id);
				}
			else{
				if($this->isCloseAble($id)){
					$this->Task->query("UPDATE `".$this->Task->tablePrefix .  $this->Task->table."`
						SET `types_id` = ".$this->settings['task_type_finished'].",
						`due` = '" . date('Y-m-d') . "'
						WHERE `".$this->Task->tablePrefix .  $this->Task->table."`.`id` = $id");
					$this->set('message', TASK_CLOSED);
					$this->set('sikeres', true);
					}			
				//ha teljes ágat zárunk le, akkor zárjuk le
				elseif($areusure){
					$eredmeny = $this->Task->find("Task.id=".$id,'bid, jid',null, 1);
					$this->Task->query('UPDATE '.$this->Task->tablePrefix .  $this->Task->table.'
							SET `types_id` = '.$this->settings['task_type_finished'] . ",
							`due` = '" . date('Y-m-d') . "'" .
							'WHERE `'.$this->Task->tablePrefix .  $this->Task->table.'`.`bid` BETWEEN ' . $eredmeny['Task']['bid'] . ' AND ' . $eredmeny['Task']['jid']);
					$this->set('message', TASK_CLOSE_BRANCH_OK);
					$this->set('sikeres', true);
					}
				else{
					$this->set('message', TASK_CLOSE_HAS_CHILDREN);
					$this->set('deletedBranchId', $id);
					$this->set('sikeres', false);
					}
				$this->set('integrityFault', $this->integrityCheck());
				$this->render('setClosed','ajax');
				}
			}
		}
	
	function isCloseAble($id){
		/*a feladat lezárható simán vagy nem?
		 
		ha az elem egy levél akkor egyből lezárható
		vagy
		ha csak lezárt gyerekei vannak akkor is lezárhatjuk
		*/
		if($this->isLikeLeaf($id) || $this->allChildIsClosed($id))
			return true;
		else
			return false;
		}
	
	/**
	* lezárt task újbóli megnyitása
	*
	* @param $id A lezárandó task id-je
	* @return nothing
	* @access public
	*/
	function setOpen($id){
		$this->Task->query("UPDATE `".$this->Task->tablePrefix .  $this->Task->table."`
					SET `types_id` = ".$this->settings['task_type_open']."
					WHERE `".$this->Task->tablePrefix .  $this->Task->table."`.`id` = $id");
		$this->set('message', TASK_OPENED);
		$this->set('sikeres', true);
		$this->set('integrityFault', $this->integrityCheck());
		$this->render('setClosed','ajax');
		}
		
	function search(){
		//ajaxos keresés a taskokban
		$this->Task->recursive = 1;
		$this->set('searchResults', $this->Task->findAll("task LIKE '%{$this->data['Task']['search']}%'",null,null, 10,1,1));
		$this->render('searchResults','ajax');
		}

	function removeClosed(){
		//lezárt feladatok törlése
		$lezartids = $this->Task->findAll('types_id = ' . $this->settings['task_type_finished'],'id');
		if(!empty($lezartids)){
			foreach($lezartids as $t){
				$this->deleteProcedure($t['Task']['id']);
				}
			$this->set('message', TASK_CLOSED_REMOVED);
			}
		else{
			$this->set('message', TASK_CLOSED_REMOVE_NOTHING);
			}
		$this->set('integrityFault',$this->integrityCheck());
		$this->set('sikeres', true);
		$this->render('removeClosed','ajax');
		}
		
	/**
	* maybe-k listája
	*
	* @return maybe lista
	* @access public
	**/
	function maybe(){
		$this->pageTitle = W2D . ELV . MAYBE;
		$this->Task->recursive = 0;
		$this->set('maybe', $this->Task->findAll('types_id = ' . $this->settings['task_type_maybe']));
		}
	
	/**
	* waiting-ek listája
	*
	* @return waiting lista
	* @access public
	**/
	function waiting(){
		$this->pageTitle = W2D . ELV . WAITING;
		$this->Task->recursive = 0;
		$this->set('waiting', $this->Task->findAll('types_id = ' . $this->settings['task_type_waiting']));
		}
		
	function isAddAble($id){
		/*hozzá lehet adni altaskot vagy nem
		ha töröltként jelölt
		vagy
		lezárt akkor nem lehet
		*/
		$allapot = $this->Task->find('Task.id='.$id,'types_id',null,false);
		if($allapot['Task']['types_id'] == $this->settings['task_type_deleted'] || $allapot['Task']['types_id'] == $this->settings['task_type_finished'])
			return false;
		else
			return true;
		}
	
}
?>